package com.ruoyi.exen.common.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.jcraft.jsch.SftpException;

import com.ruoyi.exen.common.config.SFTPConfigModel;
import com.ruoyi.exen.common.constant.FileConstant;
import com.ruoyi.exen.common.domain.SelfFile;
import com.ruoyi.exen.common.mapper.SelfFileMapper;
import com.ruoyi.exen.common.service.ISelfFileService;
import com.ruoyi.exen.common.utils.file.SFTPUtil;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.UUID;

import static com.ruoyi.common.utils.SecurityUtils.getUsername;


/**
 * 【文件】Service业务层处理
 * 
 * @author ruoyi
 * @date 2023-08-22
 */
@Service
public class ISelfFileServiceImpl implements ISelfFileService
{

    @Autowired
    private SFTPConfigModel sftpConfigModel;


    @Autowired
    private SelfFileMapper selfFileMapper;

    /**
     * 查询【文件】
     *
     * @param id 【文件】主键
     * @return 【文件】
     */
    @Override
    public SelfFile selectFileById(String id)
    {
        return selfFileMapper.selectById(id);
    }

    /**
     * 查询【文件】列表
     *
     * @param selfFile 【文件】
     * @return 【文件】
     */
    @Override
    public List<SelfFile> selectFileList(SelfFile selfFile)
    {
        return selfFileMapper.selectFileList(selfFile);
    }

    /**
     * 新增【文件】
     *
     * @param selfFile 【文件】
     * @return 结果
     */
    @Override
    public int insertFile(SelfFile selfFile)
    {
        return selfFileMapper.insertFile(selfFile);
    }

    /**
     * 修改【文件】
     *
     * @param selfFile 【文件】
     * @return 结果
     */
    @Override
    public int updateFile(SelfFile selfFile)
    {
        return selfFileMapper.updateFile(selfFile);
    }

    /**
     * 批量删除服务器文件及数据库数据
     *
     * @param ids 需要删除的文件ID
     * @return 结果
     */
    @Override
    public void deleteFileByIds(List<String> ids)
    {
        ids.forEach(id -> {
            try {
                deleteServerFile(id);
            } catch (SftpException e) {
                throw new RuntimeException(e);
            }
        });
    }

    /**
     * 删除【文件】信息
     *
     * @param id 【文件】主键
     * @return 结果
     */
    @Override
    public int deleteFileById(String id)
    {
        return selfFileMapper.deleteById(id);
    }

    /**
     * 保存文件信息数据
     * @param selfFile
     * @return
     */
    @Override
    public String saveFile(SelfFile selfFile) {
        String[] split = selfFile.getOldFileName().split("\\.");
        String s = buildFileName(split[0], selfFile.getExt(), 0);
        selfFile.setOldFileName(s);
        selfFileMapper.insert(selfFile);
        return selfFile.getId();
    }
    /**
     * 如果附件存在则在原文件名基础上加1 例 1（1）.txt
     * @param fileName 文件名
     * @param suffix 文件后缀
     * @param index    当前下标 初次调用传入0
     * @return 返回file
     */
    public String buildFileName(String fileName, String suffix, Integer index) {

        //下标不等于0开始拼后缀
        if (index != 0) {
            String[] split = fileName.split("\\.");
            if(index > 1){
                split = split[0].split("\\(");
            }
            fileName = split[0] + "(" + index + ")" + suffix;

        } else {
            fileName = fileName + suffix;
        }
        Long count = selfFileMapper.selectCount(new QueryWrapper<SelfFile>().lambda().eq(SelfFile::getOldFileName, fileName));
        //判断文件是否存在 文件不存在退出递归
        if (count > 0) {
            //每次递归给下标加1
            fileName = buildFileName(fileName, suffix, ++index);
        }
        return fileName;
    }

    /**
     * 通过ID 查询文件信息
     * @param id
     * @return
     */
    @Override
    public SelfFile findFileById(String id) {
        return selfFileMapper.selectById(id);

    }

    /**
     * 修改文件下载次数服务
     * @param id
     * @param downCounts
     */
    @Override
    public void updateFileDownCounts(String id, Integer downCounts) {
        SelfFile selfFile = new SelfFile();
        selfFile.setId(id);
        selfFile.setDownCounts(downCounts);
        selfFileMapper.updateById(selfFile);
    }

    /**
     * 上传文件 服务
     * @param file
     * @param pathType
     * @return
     * @throws Exception
     */
    @Override
    public String upload(MultipartFile file,String pathType) throws Exception {
        HashMap<String, Object> map = new HashMap<>();
        System.out.println("准备上传");
        if (file.isEmpty()) {
            return null;
        }
        //获取原始文件名称
        String originalFilename = file.getOriginalFilename();

        //获取文件后缀名
        String extension = "." + FilenameUtils.getExtension(originalFilename); //.jpg
        //获取新文件名称 命名：时间戳+UUID+后缀
        String newFileName = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date())
                + UUID.randomUUID().toString().substring(0, 4)
                + extension;

        byte[] bytes = file.getBytes();
        //上传文件到指定服务器的指定目录 自行修改
        String serverPath = "/usr/local/qms";
        String path = "/"+pathType +"/" + new SimpleDateFormat("yyyy/MM/dd/").format(new Date());
        String globalPath = serverPath + path;

        sftpConfigModel.setUploadUrl(path);
        sftpConfigModel.setUploadUrl(globalPath);
        SFTPUtil.sshSftp(bytes,sftpConfigModel,newFileName);

        //文件信息保存到数据库
        //获取文件格式
        String type = file.getContentType();
        //获取文件大小
        long size = file.getSize();
        SelfFile selfFile = new SelfFile();
        //封装进实体类
        selfFile.setOldFileName(originalFilename);
        selfFile.setNewFileName(newFileName);
        selfFile.setExt(extension);
        selfFile.setPath(path);
        selfFile.setGlobalPath(globalPath);
        selfFile.setDownCounts(0);
        selfFile.setType(type);
        selfFile.setSize(size);
        selfFile.setUploadTime(new Date());
        selfFile.setUserId(getUsername());

        boolean img = type.startsWith("image");//检测字符串是否以指定的前缀开始
        if (img) {
            selfFile.setIsImg("是");
        } else {
            selfFile.setIsImg("否");
        }
        System.out.println(selfFile);
        String s = saveFile(selfFile);
        if (!StrUtil.isEmpty(s)) {
            map.put("code", 200);
            System.out.println("上传结束");
            return s;
        } else {
            map.put("code", 500);
            return null;
        }

    }


    /**
     * 下载文件服务
     * @param id
     * @param openStyle
     * @param response
     * @throws IOException
     * @throws SftpException
     */
    @Override
    public void download(String id, String openStyle,HttpServletResponse response) throws IOException, SftpException {
            SelfFile selfFile = findFileById(id);
            //获取全路径
            String globalPath = selfFile.getGlobalPath();
            System.out.println(globalPath);
            //FileInputStream fis = new FileInputStream(new File(globalPath, selfFile.getNewFileName()));
            SFTPUtil sftpUtil = new SFTPUtil(sftpConfigModel);
            //sftp获取 文件字节
            sftpUtil.login();
            byte[] download = sftpUtil.download(globalPath, selfFile.getNewFileName());
            //将字节
            FileInputStream fileInputStream = SFTPUtil.byteToFile(download, selfFile.getOldFileName());
            sftpUtil.logout();

            //根据传过来的参数判断是下载，还是在线打开
            if ("attachment".equals(openStyle)) {
                //并更新下载次数
                selfFile.setDownCounts(selfFile.getDownCounts() + 1);
                updateFileDownCounts(id, selfFile.getDownCounts());
                //以附件形式下载  点击会提供对话框选择另存为：
                response.setHeader("content-disposition", "attachment;filename=" + URLEncoder.encode(selfFile.getOldFileName(), "utf-8"));
            }
            //获取输出流
            ServletOutputStream os = response.getOutputStream();
            //利用IO流工具类实现流文件的拷贝，（输出显示在浏览器上在线打开方式）
            IOUtils.copy(fileInputStream, os);
            IOUtils.closeQuietly(fileInputStream);
            IOUtils.closeQuietly(os);

    }

    /**
     * 删除文件接口
     * @param id 项目ID
     * @return
     */
    @Override
    public void deleteServerFile(String id) throws SftpException {
        SelfFile selfFile = findFileById(id);
        if(ObjectUtil.isEmpty(selfFile)){
            return;
        }
        //获取全路径
        String globalPath = selfFile.getGlobalPath();
        SFTPUtil sftpUtil = new SFTPUtil(sftpConfigModel);
        //sftp获取 文件字节
        sftpUtil.login();
        sftpUtil.delete(globalPath, selfFile.getNewFileName());
        sftpUtil.logout();
        //删除数据库数据
        selfFileMapper.deleteById(id);
    }

    /**
     * 获取该文件的路径
     * @param id
     * @return
     */
    @Override
    public String getFileUrl(String id) {
        if(StrUtil.isEmpty(id))
        {
            return null;
        }
        SelfFile selfFile = selectFileById(id);
        String url = "http://" +  FileConstant.getHost() +":" + FileConstant.getPort() + selfFile.getPath() + selfFile.getNewFileName();
        return url;
    }

    /**
     * @param directory 删除路径，会删除本路径注意
     * @return void
     * @Description //TODO
     * @Date 17:14 2020/11/2
     * @Param
     **/
    public void deleteSFTP(String directory) {

    }

}
